<?php
function insertData($sql)
{
	require_once("condb.php");
	$a = mysql_query($sql);
	$id = mysql_insert_id();
	return $id;
}
	
abstract class XmlStreamer
{
	private $handle;
	private $totalBytes;
	private $readBytes = 0;
	private $nodeIndex = 0;
	private $chunk = "";
	private $chunkSize;
	private $readFromChunkPos;
	
	private $rootNode;
	private $customRootNode;
	
	/**
	* @param $mixed Path to XML file OR file handle
	* @param $chunkSize Bytes to read per cycle (Optional, default is 16 KiB)
	* @param $customRootNode Specific root node to use (Optional)
	* @param $totalBytes Xml file size - Required if supplied file handle
	*/
	public function __construct($mixed, $chunkSize = 16384, $customRootNode = null, $totalBytes = null, $customChildNode = null) {
	if (is_string($mixed)) {
	$this->handle = fopen($mixed, "r");
	if (isset($totalBytes)) {
	$this->totalBytes = $totalBytes;
	} else {
	$this->totalBytes = filesize($mixed);
	}
	} else if (is_resource($mixed)){
	$this->handle = $mixed;
	if (!isset($totalBytes)) {
	throw new Exception("totalBytes parameter required when supplying a file handle.");
	}
	$this->totalBytes = $totalBytes;
	}
	
	$this->chunkSize = $chunkSize;
	$this->customRootNode = $customRootNode;
	$this->customChildNode = $customChildNode;
	}
	
	/**
	* Gets called for every XML node that is found as a child to the root node
	* @param $xmlString Complete XML tree of the node as a string
	* @param $elementName Name of the node for easy access
	* @param $nodeIndex Zero-based index that increments for every node
	* @return If false is returned, the streaming will stop
	*/
	abstract public function processNode($xmlString, $elementName, $nodeIndex);
	
	/**
	* Gets the total read bytes so far
	*/
	public function getReadBytes() {
	return $this->readBytes;
	}
	
	/**
	* Gets the total file size of the xml
	*/
	public function getTotalBytes() {
	return $this->totalBytes;
	}
	
	/**
	* Starts the streaming and parsing of the XML file
	*/
	public function parse() {
	$counter = 0;
	$continue = true;
	while ($continue) {
	$continue = $this->readNextChunk();
	
	$counter++;
	if (!isset($this->rootNode)) {
	// Find root node
	if (isset($this->customRootNode)) {
	$customRootNodePos = strpos($this->chunk, "<{$this->customRootNode}");
	if ($customRootNodePos !== false) {
	// Found custom root node
	// Support attributes
	$closer = strpos(substr($this->chunk, $customRootNodePos), ">");
	$readFromChunkPos = $customRootNodePos + $closer + 1;
	
	// Custom child node?
	if (isset($this->customChildNode)) {
	// Find it in the chunk
	$customChildNodePos = strpos(substr($this->chunk, $readFromChunkPos), "<{$this->customChildNode}");
	if ($customChildNodePos !== false) {
	// Found it!
	$readFromChunkPos = $readFromChunkPos + $customChildNodePos;
	} else {
	// Didn't find it - read a larger chunk and do everything again
	continue;
	}
	}
	
	$this->rootNode = $this->customRootNode;
	$this->readFromChunkPos = $readFromChunkPos;
	} else {
	// Clear chunk to save memory, it doesn't contain the root anyway
	$this->readFromChunkPos = 0;
	$this->chunk = "";
	continue;
	}
	} else {
	preg_match("/<([a-zA-Z][^>]+)>/", $this->chunk, $matches);
	if (isset($matches[1])) {
	// Found root node
	$this->rootNode = $matches[1];
	$this->readFromChunkPos = strpos($this->chunk, $matches[0]) + strlen($matches[0]);
	} else {
	// Clear chunk to save memory, it doesn't contain the root anyway
	$this->readFromChunkPos = 0;
	$this->chunk = "";
	continue;
	}
	}
	}
	
	while (true) {
	$fromChunkPos = substr($this->chunk, $this->readFromChunkPos);
	
	// Find element
	preg_match("/<([a-zA-Z][^>]+)>/", $fromChunkPos, $matches);
	if (isset($matches[1])) {
	// Found element
	$element = $matches[1];
	
	// Is there an end to this element tag?
	$spacePos = strpos($element, " ");
	if ($spacePos !== false) {
	$endTag = "</" . substr($element, 0, $spacePos) . ">";
	} else {
	$endTag = "</$element>";
	}
	$endTagPos = strpos($fromChunkPos, $endTag);
	
	if ($endTagPos !== false) {
	// Found end tag
	$endTagEndPos = $endTagPos + strlen($endTag);
	$elementWithChildren = substr($fromChunkPos, 0, $endTagEndPos);
	$continueParsing = $this->processNode($elementWithChildren, $element, $this->nodeIndex++);
	$this->chunk = substr($this->chunk, strpos($this->chunk, $endTag) + strlen($endTag));
	$this->readFromChunkPos = 0;
	
	if (isset($continueParsing) && $continueParsing === false) {
	break(2);
	}
	} else {
	break;
	}
	} else {
	break;
	}
	}
	}
	return isset($this->rootNode);
	fclose($this->handle);
	}
	
	private function readNextChunk() {
	$this->chunk .= fread($this->handle, $this->chunkSize);
	$this->readBytes += $this->chunkSize;
	if ($this->readBytes >= $this->totalBytes) {
	$this->readBytes = $this->totalBytes;
	return false;
	}
	return true;
	}
}

class SimpleXmlStreamer extends XmlStreamer {
	public function processNode($xmlString, $elementName, $nodeIndex) {
		$xml = simplexml_load_string($xmlString);
		$output=array();
		$sub_sql='';
		if($xml)
		foreach($xml->device as $row)
		{
			$a=$row->group;
			$a=$a[0];
			//$b=array('handset'=>'','manufacturer'=>'');
			$b=array();
			if(isset($a->capability))
			{
				foreach($a->capability as $value)
				{
					if($value['name']=='model_name')
					{
						$b['handset']=$value['value'];
					}
					if($value['name']=='brand_name')
					{
						$b['manufacturer']=$value['value'];
					}
					if(isset($b['handset']) && isset($b['manufacturer']))
						break;
				}
			}
			if(!empty($b))
			{
				$output[]=$b;
				if(isset($b['handset']) && $b['handset']!='' && isset($b['manufacturer']) && $b['manufacturer']!='')
				{
					$hanset=mb_strtoupper($b['handset']);
					$manufacturer=mb_strtoupper($b['manufacturer']);
					$sub_sql.='("'.mysql_escape_string($manufacturer).'","'.mysql_escape_string($hanset).'"),';
				}
			}
		}
		//var_dump($output);
		if($sub_sql!='')
		{
			$sub_sql=rtrim($sub_sql,',');
			$sql="INSERT IGNORE INTO c_mobile_handset_2(`manufacturer`, `handset`) VALUES ".$sub_sql."";
			insertData($sql);
			echo "Done!";
		}
		//$something = (string)$xml->Something->SomethingElse->ReadThis;
		//echo "$nodeIndex: Extracted string '$something' from parent node '$elementName'\n";
		return true;
	}
}
ini_set('memory_limit', '128M');
$streamer = new SimpleXmlStreamer("wurfl.xml");
$streamer->parse();
?>
